import json
import logging

from django.conf import settings
from codes.models import Code
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone

logger = logging.getLogger(__name__)

# 对战状态选择
BATTLE_STATUS_CHOICES = [
    ('pending', '等待中'),
    ('running', '进行中'),
    ('finished', '已完成'),
    ('error', '错误'),
]

# 对战结果选择
BATTLE_RESULT_CHOICES = [
    ('player1_win', '玩家1获胜'),
    ('player2_win', '玩家2获胜'),
    ('draw', '平局'),
    ('error', '错误'),
]

# 对战类型选择
BATTLE_TYPE_CHOICES = [
    ('ranked', '排位赛'),
    ('practice', '练习赛'),
    ('worldcup_regular', '世界杯常规赛'),
    ('worldcup_championship', '世界杯冠军赛'),
]


class Battle(models.Model):
    """对战记录模型"""

    # 对战双方
    player1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='battles_as_player1', verbose_name='玩家1')
    player2 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='battles_as_player2', verbose_name='玩家2')

    # 使用的代码版本
    player1_code = models.ForeignKey(Code, on_delete=models.CASCADE, related_name='battles_as_code1', verbose_name='玩家1代码')
    player2_code = models.ForeignKey(Code, on_delete=models.CASCADE, related_name='battles_as_code2', verbose_name='玩家2代码')

    # 对战信息
    status = models.CharField(max_length=20, choices=BATTLE_STATUS_CHOICES, default='pending', verbose_name='状态')
    result = models.CharField(max_length=20, choices=BATTLE_RESULT_CHOICES, null=True, blank=True, verbose_name='结果')
    battle_type = models.CharField(max_length=25, choices=BATTLE_TYPE_CHOICES, default='ranked', verbose_name='对战类型')

    # 时间信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    started_at = models.DateTimeField(null=True, blank=True, verbose_name='开始时间')
    finished_at = models.DateTimeField(null=True, blank=True, verbose_name='结束时间')

    # 对战配置
    map_config = models.JSONField(default=dict, verbose_name='地图配置')
    game_config = models.JSONField(default=dict, verbose_name='游戏配置')
    init_command = models.JSONField(default=dict, verbose_name='初始化命令')
    end_command = models.JSONField(default=dict, verbose_name='结束命令')

    # 错误信息
    error_message = models.TextField(blank=True, null=True, verbose_name='错误信息')

    # 统计信息
    total_rounds = models.IntegerField(default=0, verbose_name='总回合数')
    player1_score = models.IntegerField(default=0, verbose_name='玩家1得分')
    player2_score = models.IntegerField(default=0, verbose_name='玩家2得分')

    player1_stats = models.JSONField(default=dict, verbose_name='玩家1统计信息')
    player2_stats = models.JSONField(default=dict, verbose_name='玩家2统计信息')

    # 权限控制
    is_public = models.BooleanField(default=True, verbose_name='是否公开')
    save_round_inputs = models.BooleanField(default=False, verbose_name='保存回合输入数据')

    # 精彩战斗标记
    is_exciting = models.BooleanField(default=False, verbose_name='是否为精彩战斗')
    excitement_score = models.FloatField(default=0.0, verbose_name='精彩程度评分')
    is_manually_marked = models.BooleanField(default=False, verbose_name='是否手动标记')
    excitement_calculated_at = models.DateTimeField(null=True, blank=True, verbose_name='精彩程度计算时间')

    class Meta:
        verbose_name = '对战记录'
        verbose_name_plural = '对战记录'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status', 'created_at']),
            models.Index(fields=['result', 'finished_at']),
            models.Index(fields=['player1', 'status']),
            models.Index(fields=['player2', 'status']),
            models.Index(fields=['player1_code']),
            models.Index(fields=['player2_code']),
            models.Index(fields=['is_public', 'status']),
            models.Index(fields=['is_exciting', '-excitement_score']),
            models.Index(fields=['excitement_score']),
            models.Index(fields=['battle_type', 'status']),
        ]

    def __str__(self):
        return f'{self.player1.username} vs {self.player2.username} - {self.get_status_display()}'

    def get_duration(self):
        """获取对战持续时间"""
        if self.started_at and self.finished_at:
            return self.finished_at - self.started_at
        return None

    def get_winner(self):
        """获取获胜者"""
        if self.result == 'player1_win':
            return self.player1
        elif self.result == 'player2_win':
            return self.player2
        return None

    @property
    def player1_win_rate(self):
        """计算玩家1的实时胜率"""
        total_battles = Battle.objects.filter(
            models.Q(player1=self.player1) | models.Q(player2=self.player1), status='finished'
        ).count()

        if total_battles == 0:
            return 0.0

        wins = Battle.objects.filter(
            models.Q(player1=self.player1, result='player1_win') | models.Q(player2=self.player1, result='player2_win'),
            status='finished',
        ).count()

        return (wins / total_battles) * 100

    @property
    def player2_win_rate(self):
        """计算玩家2的实时胜率"""
        total_battles = Battle.objects.filter(
            models.Q(player1=self.player2) | models.Q(player2=self.player2), status='finished'
        ).count()

        if total_battles == 0:
            return 0.0

        wins = Battle.objects.filter(
            models.Q(player1=self.player2, result='player1_win') | models.Q(player2=self.player2, result='player2_win'),
            status='finished',
        ).count()

        return (wins / total_battles) * 100

    def get_player_stats(self, user):
        """获取指定玩家的实时统计信息"""
        # 总对战数（排除自己对战自己的情况）
        total_battles = Battle.objects.filter(models.Q(player1=user) | models.Q(player2=user), status='finished').exclude(
            player1=models.F('player2')
        )
        total_battles_count = total_battles.count()

        if total_battles_count == 0:
            return {
                'total_battles': 0,
                'wins': 0,
                'losses': 0,
                'draws': 0,
                'win_rate': 0.0,
                'total_score': 0,
                'average_score': 0.0,
            }

        # 胜利数（排除自己对战自己的情况）
        wins = (
            Battle.objects.filter(
                models.Q(player1=user, result='player1_win') | models.Q(player2=user, result='player2_win'), status='finished'
            )
            .exclude(player1=models.F('player2'))
            .count()
        )

        # 平局数（排除自己对战自己的情况）
        draws = (
            Battle.objects.filter(models.Q(player1=user) | models.Q(player2=user), result='draw', status='finished')
            .exclude(player1=models.F('player2'))
            .count()
        )

        # 失败数（排除自己对战自己的情况）
        # losses = (
        #     Battle.objects.filter(
        #         models.Q(player1=user, result='player2_win') | models.Q(player2=user, result='player1_win'), status='finished'
        #     )
        #     .exclude(player1=models.F('player2'))
        #     .count()
        # )
        losses = total_battles_count - wins - draws

        # 计算总得分和平均得分（排除自己对战自己的情况）
        battles = Battle.objects.filter(models.Q(player1=user) | models.Q(player2=user), status='finished').exclude(
            player1=models.F('player2')
        )

        total_score = 0
        for battle in battles:
            if battle.player1 == user:
                total_score += battle.player1_score or 0
            else:
                total_score += battle.player2_score or 0

        average_score = total_score / total_battles_count if total_battles_count > 0 else 0.0
        win_rate = (wins / total_battles_count) * 100 if total_battles_count > 0 else 0.0

        return {
            'total_battles': total_battles_count,
            'wins': wins,
            'losses': losses,
            'draws': draws,
            'win_rate': win_rate,
            'total_score': total_score,
            'average_score': average_score,
        }

    def get_player1_base_health_percentage(self):
        """获取玩家1基地血量百分比"""
        base_max_health = self.game_config.get('base_max_health', 600)
        current_health = self.player1_stats.get('baseHealth', 0)
        if base_max_health == 0:
            return 0
        return round((current_health / base_max_health) * 100, 1)

    def get_player2_base_health_percentage(self):
        """获取玩家2基地血量百分比"""
        base_max_health = self.game_config.get('base_max_health', 600)
        current_health = self.player2_stats.get('baseHealth', 0)
        if base_max_health == 0:
            return 0
        return round((current_health / base_max_health) * 100, 1)

    def get_detailed_player_stats(self, user):
        """获取指定玩家的详细统计信息，包括战斗数据"""
        # 获取基础统计信息
        basic_stats = self.get_player_stats(user)

        # 获取所有已完成的对战（排除自己对战自己的情况）
        battles = Battle.objects.filter(models.Q(player1=user) | models.Q(player2=user), status='finished').exclude(
            player1=models.F('player2')
        )

        # 初始化详细统计数据
        detailed_stats = {
            'total_kills': 0,
            'total_deaths': 0,
            'total_damage_dealt': 0,
            'total_damage_received': 0,
            'total_healing': 0,
            'total_command_fail_count': 0,
            'total_rmb': 0,
            'average_base_health': 0.0,
            'kd_ratio': 0.0,
        }

        total_base_health = 0
        battle_count = 0

        for battle in battles:
            # 确定玩家是player1还是player2
            if battle.player1 == user:
                player_stats = battle.player1_stats
            else:
                player_stats = battle.player2_stats

            # 提取统计数据
            if player_stats:
                stats = player_stats.get('stats', {})
                detailed_stats['total_kills'] += stats.get('kills', 0)
                detailed_stats['total_deaths'] += stats.get('deaths', 0)
                detailed_stats['total_damage_dealt'] += stats.get('totalDamageDealt', 0)
                detailed_stats['total_damage_received'] += stats.get('totalDamageReceived', 0)
                detailed_stats['total_healing'] += stats.get('totalHealing', 0)
                detailed_stats['total_command_fail_count'] += stats.get('commandFailCount', 0)
                detailed_stats['total_rmb'] += player_stats.get('rmb', 0)

                base_health = player_stats.get('baseHealth', 0)
                if base_health > 0:
                    total_base_health += base_health
                    battle_count += 1

        # 计算平均基础生命值
        if battle_count > 0:
            detailed_stats['average_base_health'] = total_base_health / battle_count

        # 计算KD比率
        if detailed_stats['total_deaths'] > 0:
            detailed_stats['kd_ratio'] = detailed_stats['total_kills'] / detailed_stats['total_deaths']
        else:
            detailed_stats['kd_ratio'] = detailed_stats['total_kills']

        # 合并基础统计和详细统计
        return {**basic_stats, **detailed_stats}

    def get_execution_stats(self):
        """获取战斗的代码执行统计信息"""
        rounds = self.rounds.all()

        player1_total_successful = sum(r.player1_successful_commands for r in rounds)
        player1_total_failed = sum(r.player1_failed_commands for r in rounds)
        player2_total_successful = sum(r.player2_successful_commands for r in rounds)
        player2_total_failed = sum(r.player2_failed_commands for r in rounds)

        # 收集所有失败命令详情
        player1_all_failed_details = []
        player2_all_failed_details = []

        for round_obj in rounds:
            player1_all_failed_details.extend(round_obj.player1_failed_commands_detail)
            player2_all_failed_details.extend(round_obj.player2_failed_commands_detail)

        return {
            'player1': {
                'successful_commands': player1_total_successful,
                'failed_commands': player1_total_failed,
                'total_commands': player1_total_successful + player1_total_failed,
                'success_rate': (player1_total_successful / (player1_total_successful + player1_total_failed) * 100)
                if (player1_total_successful + player1_total_failed) > 0
                else 0,
                'failed_details': player1_all_failed_details,
            },
            'player2': {
                'successful_commands': player2_total_successful,
                'failed_commands': player2_total_failed,
                'total_commands': player2_total_successful + player2_total_failed,
                'success_rate': (player2_total_successful / (player2_total_successful + player2_total_failed) * 100)
                if (player2_total_successful + player2_total_failed) > 0
                else 0,
                'failed_details': player2_all_failed_details,
            },
        }

    def get_produced_units_stats(self):
        """统计双方生产单位数量（基于每回合命令执行详情）"""
        rounds = list(self.rounds.all())

        def count_units(details: list):
            total = 0
            by_type = {}
            for d in details or []:
                # 需要有类型且非错误
                if d.get('isError', False):
                    continue
                cmd_type = d.get('type')
                if cmd_type != 'swap':
                    continue
                cmd = d.get('command', {})
                param = cmd.get('param', {})
                target = param.get('target', {})
                unit_type = target.get('utype')
                total += 1
                by_type[unit_type] = by_type.get(unit_type, 0) + 1
            return total, by_type

        p1_details = []
        p2_details = []
        for r in rounds:
            p1_details.extend(r.player1_command_execution_details or [])
            p2_details.extend(r.player2_command_execution_details or [])

        p1_total, p1_by_type = count_units(p1_details)
        p2_total, p2_by_type = count_units(p2_details)

        total_units = p1_total + p2_total


        return {
            'player1': {'total': p1_total, 'by_type': p1_by_type},
            'player2': {'total': p2_total, 'by_type': p2_by_type},
            'total_units': total_units,
        }

    def calculate_excitement_score(self):
        """计算精彩程度评分"""
        # 获取精彩战斗配置
        config = getattr(settings, 'EXCITING_BATTLE', {})

        if not config.get('ENABLED', True):
            return 0.0

        # 获取评分权重配置
        weights = config.get('SCORING_WEIGHTS', {
            'BATTLE_INTENSITY': 35,
            'STRATEGIC_COMPLEXITY': 25,
            'ECONOMIC_DEVELOPMENT': 25,
            'COMMAND_EFFICIENCY': 15,
        })

        # 获取各项评分配置
        intensity_config = config.get('BATTLE_INTENSITY', {})
        complexity_config = config.get('STRATEGIC_COMPLEXITY', {})
        economic_config = config.get('ECONOMIC_DEVELOPMENT', {})
        efficiency_config = config.get('COMMAND_EFFICIENCY', {})

        # 获取双方统计数据（注意：实际结构为顶层字段 + 嵌套 stats 字段）
        p1_stats = self.player1_stats or {}
        p2_stats = self.player2_stats or {}
        p1_core = p1_stats.get('stats', {})
        p2_core = p2_stats.get('stats', {})

        # 1. 战斗激烈程度评分（默认35分）
        intensity_score = 0
        debug_details = {
            'BATTLE_INTENSITY': {},
            'STRATEGIC_COMPLEXITY': {},
            'ECONOMIC_DEVELOPMENT': {},
            'COMMAND_EFFICIENCY': {},
        }

        # 1.1 击杀数评分（默认15分）
        # 实际数据在嵌套 stats 中
        total_kills = p1_core.get('kills', 0) + p2_core.get('kills', 0)
        kills_config = intensity_config.get('KILLS_SCORING', {})
        kills_thresholds = kills_config.get('THRESHOLDS', [
            (150, 15), (100, 12), (60, 9), (30, 6), (15, 3), (0, 0)
        ])
        kills_awarded = 0
        kills_threshold_hit = None
        for threshold, score in kills_thresholds:
            if total_kills >= threshold:
                intensity_score += score
                kills_awarded = score
                kills_threshold_hit = threshold
                break
        debug_details['BATTLE_INTENSITY']['kills'] = {
            'total_kills': total_kills,
            'threshold_hit': kills_threshold_hit,
            'score_awarded': kills_awarded,
        }

        # 1.2 伤害量评分（默认12分）
        # 实际数据键为 totalDamageDealt
        total_damage = p1_core.get('totalDamageDealt', 0) + p2_core.get('totalDamageDealt', 0)
        damage_config = intensity_config.get('DAMAGE_SCORING', {})
        damage_thresholds = damage_config.get('THRESHOLDS', [
            (10000, 12), (8000, 10), (6000, 8), (4000, 6), (2000, 3), (0, 0)
        ])
        damage_awarded = 0
        damage_threshold_hit = None
        for threshold, score in damage_thresholds:
            if total_damage >= threshold:
                intensity_score += score
                damage_awarded = score
                damage_threshold_hit = threshold
                break
        debug_details['BATTLE_INTENSITY']['damage'] = {
            'total_damage': total_damage,
            'threshold_hit': damage_threshold_hit,
            'score_awarded': damage_awarded,
        }

        # 1.3 治疗量评分（默认8分）
        # 实际数据键为 totalHealing
        total_healing = p1_core.get('totalHealing', 0) + p2_core.get('totalHealing', 0)
        healing_config = intensity_config.get('HEALING_SCORING', {})
        healing_thresholds = healing_config.get('THRESHOLDS', [
            (1000, 8), (800, 6), (500, 4), (200, 2), (0, 0)
        ])
        healing_awarded = 0
        healing_threshold_hit = None
        for threshold, score in healing_thresholds:
            if total_healing >= threshold:
                intensity_score += score
                healing_awarded = score
                healing_threshold_hit = threshold
                break
        debug_details['BATTLE_INTENSITY']['healing'] = {
            'total_healing': total_healing,
            'threshold_hit': healing_threshold_hit,
            'score_awarded': healing_awarded,
        }
        debug_details['BATTLE_INTENSITY']['total'] = intensity_score

        # 2. 战略复杂度评分（默认25分）
        complexity_score = 0

        # 2.1 生产单位总数评分（默认25分）
        # 基于命令执行详情统计生产单位数量
        produced_stats = self.get_produced_units_stats()
        total_units = produced_stats.get('total_units', 0)
        units_config = complexity_config.get('UNITS_PRODUCED_SCORING', {})
        units_thresholds = units_config.get('THRESHOLDS', [
            (400, 25), (300, 20), (200, 15), (100, 10), (50, 5), (0, 0)
        ])
        units_awarded = 0
        units_threshold_hit = None
        for threshold, score in units_thresholds:
            if total_units >= threshold:
                complexity_score += score
                units_awarded = score
                units_threshold_hit = threshold
                break
        debug_details['STRATEGIC_COMPLEXITY']['units_produced'] = {
            'total_units': total_units,
            'player1_by_type': produced_stats.get('player1', {}).get('by_type', {}),
            'player2_by_type': produced_stats.get('player2', {}).get('by_type', {}),
            'threshold_hit': units_threshold_hit,
            'score_awarded': units_awarded,
        }
        debug_details['STRATEGIC_COMPLEXITY']['total'] = complexity_score

        # 3. 经济发展评分（默认25分）
        economic_score = 0

        # 3.1 经济活动综合评分（替代仅用最终余额的方案）
        econ_stats = self.get_economy_stats()
        p1_econ = econ_stats.get('player1', {})
        p2_econ = econ_stats.get('player2', {})

        # 合并总体指标
        combined_income = (p1_econ.get('income_total', 0) or 0) + (p2_econ.get('income_total', 0) or 0)
        combined_spent = (p1_econ.get('spent_total', 0) or 0) + (p2_econ.get('spent_total', 0) or 0)
        peak_rmb = max(p1_econ.get('peak_rmb', 0) or 0, p2_econ.get('peak_rmb', 0) or 0)
        avg_rmb = ((p1_econ.get('avg_rmb', 0.0) or 0.0) + (p2_econ.get('avg_rmb', 0.0) or 0.0)) / 2.0
        final_rmb = (p1_econ.get('final_rmb', 0) or 0) + (p2_econ.get('final_rmb', 0) or 0)

        economic_config = (getattr(settings, 'EXCITING_BATTLE', {}).get('ECONOMIC_DEVELOPMENT', {}) or {})
        activity_config = economic_config.get('ECONOMIC_ACTIVITY_SCORING', {})

        # 直接获取阈值配置，如果不存在则使用默认值
        income_thresholds = activity_config.get('INCOME_TOTAL_THRESHOLDS', [(20000, 4), (12000, 3), (6000, 2), (2000, 1), (0, 0)])
        spent_thresholds = activity_config.get('SPENT_TOTAL_THRESHOLDS', [(20000, 4), (12000, 3), (6000, 2), (2000, 1), (0, 0)])
        peak_thresholds = activity_config.get('PEAK_RMB_THRESHOLDS', [(10000, 3), (6000, 2), (3000, 1), (0, 0)])
        avg_thresholds = activity_config.get('AVG_RMB_THRESHOLDS', [(6000, 3), (3000, 2), (1500, 1), (0, 0)])
        final_thresholds = activity_config.get('FINAL_RMB_THRESHOLDS', [(8000, 1), (0, 0)])

        def _award(value, thresholds):
            hit = None
            score = 0
            for t, s in thresholds:
                if value >= t:
                    hit = t
                    score = s
                    break
            return score, hit

        income_awarded, income_hit = _award(combined_income, income_thresholds)
        spent_awarded, spent_hit = _award(combined_spent, spent_thresholds)
        peak_awarded, peak_hit = _award(peak_rmb, peak_thresholds)
        avg_awarded, avg_hit = _award(avg_rmb, avg_thresholds)
        final_awarded, final_hit = _award(final_rmb, final_thresholds)

        economic_score += income_awarded + spent_awarded + peak_awarded + avg_awarded + final_awarded

        debug_details['ECONOMIC_DEVELOPMENT']['economy'] = {
            'combined_income_total': combined_income,
            'combined_spent_total': combined_spent,
            'peak_rmb': peak_rmb,
            'avg_rmb': round(avg_rmb, 2),
            'final_rmb': final_rmb,
            'income_threshold_hit': income_hit,
            'spent_threshold_hit': spent_hit,
            'peak_threshold_hit': peak_hit,
            'avg_threshold_hit': avg_hit,
            'final_threshold_hit': final_hit,
            'score_awarded': {
                'income': income_awarded,
                'spent': spent_awarded,
                'peak': peak_awarded,
                'avg': avg_awarded,
                'final': final_awarded,
            },
            'player1': p1_econ,
            'player2': p2_econ,
        }

        # 3.2 战略多样性评分（默认10分，保留原逻辑）
        produced_stats = self.get_produced_units_stats()
        p1_types = set((produced_stats.get('player1', {}).get('by_type', {}) or {}).keys())
        p2_types = set((produced_stats.get('player2', {}).get('by_type', {}) or {}).keys())
        unit_types = sorted(list(p1_types.union(p2_types)))

        diversity_config = economic_config.get('DIVERSITY_SCORING', {})
        diversity_thresholds = diversity_config.get('THRESHOLDS', [
            (5, 10), (4, 8), (3, 6), (2, 3), (1, 0)
        ])
        diversity_awarded = 0
        diversity_threshold_hit = None
        for threshold, score in diversity_thresholds:
            if len(unit_types) >= threshold:
                economic_score += score
                diversity_awarded = score
                diversity_threshold_hit = threshold
                break

        debug_details['ECONOMIC_DEVELOPMENT']['diversity'] = {
            'unit_types': unit_types,
            'count': len(unit_types),
            'player1_by_type': produced_stats.get('player1', {}).get('by_type', {}),
            'player2_by_type': produced_stats.get('player2', {}).get('by_type', {}),
            'threshold_hit': diversity_threshold_hit,
            'score_awarded': diversity_awarded,
        }
        debug_details['ECONOMIC_DEVELOPMENT']['total'] = economic_score

        # 4. 命令执行效率评分（默认15分）
        efficiency_score = 0

        # 4.1 命令成功率评分（默认15分）
        # 实际命令统计通过回合聚合获取
        execution = self.get_execution_stats()
        p1_total_commands = execution.get('player1', {}).get('total_commands', 0)
        p1_success_commands = execution.get('player1', {}).get('successful_commands', 0)
        p2_total_commands = execution.get('player2', {}).get('total_commands', 0)
        p2_success_commands = execution.get('player2', {}).get('successful_commands', 0)

        total_commands = (p1_total_commands or 0) + (p2_total_commands or 0)
        total_success = (p1_success_commands or 0) + (p2_success_commands or 0)

        success_rate = 0
        success_awarded = 0
        success_threshold_hit = None
        if total_commands > 0:
            success_rate = (total_success / total_commands) * 100
            success_config = efficiency_config.get('SUCCESS_RATE_SCORING', {})
            success_thresholds = success_config.get('THRESHOLDS', [
                (95, 15), (90, 12), (85, 9), (80, 6), (70, 3), (0, 0)
            ])
            for threshold, score in success_thresholds:
                if success_rate >= threshold:
                    efficiency_score += score
                    success_awarded = score
                    success_threshold_hit = threshold
                    break
        debug_details['COMMAND_EFFICIENCY']['success_rate'] = {
            'p1_total_commands': p1_total_commands,
            'p1_successful': p1_success_commands,
            'p2_total_commands': p2_total_commands,
            'p2_successful': p2_success_commands,
            'total_commands': total_commands,
            'total_success': total_success,
            'success_rate': round(success_rate, 2) if total_commands > 0 else 0,
            'threshold_hit': success_threshold_hit,
            'score_awarded': success_awarded,
        }
        debug_details['COMMAND_EFFICIENCY']['total'] = efficiency_score

        # 计算总分
        total_score = intensity_score + complexity_score + economic_score + efficiency_score

        return round(total_score, 2)

    def get_economy_stats(self):
        """获取经济活动统计信息"""
        rounds = list(self.rounds.order_by('round_number'))

        # 尝试从命令详情中反推出玩家ID映射（与battleStats.players的key一致）
        p1_id = None
        p2_id = None
        for r in rounds:
            if not p1_id:
                for d in r.player1_command_execution_details or []:
                    pid = d.get('player')
                    if pid:
                        p1_id = pid
                        break
            if not p2_id:
                for d in r.player2_command_execution_details or []:
                    pid = d.get('player')
                    if pid:
                        p2_id = pid
                        break
            if p1_id and p2_id:
                break

        p1_series = []
        p2_series = []
        # 若无法通过命令详情获取ID，首个回合按players字典顺序兜底
        fallback_set = False

        for r in rounds:
            players = ((r.round_data or {}).get('battleStats', {}) or {}).get('players', {}) or {}

            if not (p1_id and p2_id) and players and not fallback_set:
                keys = list(players.keys())
                if len(keys) >= 1 and not p1_id:
                    p1_id = keys[0]
                if len(keys) >= 2 and not p2_id:
                    p2_id = keys[1]
                fallback_set = True

            if p1_id and p1_id in players:
                p1_series.append(int(players[p1_id].get('rmb', 0) or 0))
            if p2_id and p2_id in players:
                p2_series.append(int(players[p2_id].get('rmb', 0) or 0))

        def calc_metrics(series):
            if not series:
                return {
                    'income_total': 0,
                    'spent_total': 0,
                    'peak_rmb': 0,
                    'avg_rmb': 0.0,
                    'final_rmb': 0,
                    'series': [],
                }
            income_total = 0
            spent_total = 0
            peak_rmb = max(series)
            avg_rmb = (sum(series) / len(series)) if series else 0.0
            final_rmb = series[-1]
            prev = series[0]
            for v in series[1:]:
                delta = v - prev
                if delta > 0:
                    income_total += delta
                elif delta < 0:
                    spent_total += -delta
                prev = v
            return {
                'income_total': int(income_total),
                'spent_total': int(spent_total),
                'peak_rmb': int(peak_rmb),
                'avg_rmb': float(avg_rmb),
                'final_rmb': int(final_rmb),
                'series': series,
            }

        p1_metrics = calc_metrics(p1_series)
        p2_metrics = calc_metrics(p2_series)

        return {
            'player1': p1_metrics,
            'player2': p2_metrics,
            'rounds': len(rounds),
            'player_ids': {'player1': p1_id, 'player2': p2_id},
        }

    def update_excitement_status(self, manual_mark=False):
        """更新精彩战斗状态"""
        # 获取精彩战斗配置
        config = getattr(settings, 'EXCITING_BATTLE', {})
        threshold = config.get('AUTO_MARK_THRESHOLD', 70.0)
        auto_calculate = config.get('AUTOMATION', {}).get('AUTO_CALCULATE_ON_FINISH', True)
        auto_mark = config.get('AUTOMATION', {}).get('AUTO_MARK_ON_THRESHOLD', True)

        if not manual_mark and auto_calculate:
            # 自动计算精彩程度
            self.excitement_score = self.calculate_excitement_score()
            if auto_mark:
                self.is_exciting = self.excitement_score >= threshold
            self.excitement_calculated_at = timezone.now()

        self.save(update_fields=['is_exciting', 'excitement_score', 'is_manually_marked', 'excitement_calculated_at'])

    def mark_as_exciting(self, is_exciting=True, manual=True):
        """手动标记为精彩战斗"""
        self.is_exciting = is_exciting
        self.is_manually_marked = manual
        if not manual:
            self.excitement_score = self.calculate_excitement_score()
        self.excitement_calculated_at = timezone.now()
        self.save(update_fields=['is_exciting', 'excitement_score', 'is_manually_marked', 'excitement_calculated_at'])


class BattleRound(models.Model):
    """对战回合数据模型（用于详细分析）"""

    battle = models.ForeignKey(Battle, on_delete=models.CASCADE, related_name='rounds', verbose_name='对战记录')
    round_number = models.IntegerField(verbose_name='回合数')

    # 回合数据
    round_data = models.JSONField(verbose_name='回合数据')

    # 玩家状态
    player1_units = models.JSONField(default=list, verbose_name='玩家1单位状态')
    player2_units = models.JSONField(default=list, verbose_name='玩家2单位状态')

    # 玩家命令数据
    player1_actions = models.JSONField(default=list, verbose_name='玩家1命令')
    player2_actions = models.JSONField(default=list, verbose_name='玩家2命令')

    # 命令执行统计
    player1_successful_commands = models.IntegerField(default=0, verbose_name='玩家1成功命令数')
    player1_failed_commands = models.IntegerField(default=0, verbose_name='玩家1失败命令数')
    player2_successful_commands = models.IntegerField(default=0, verbose_name='玩家2成功命令数')
    player2_failed_commands = models.IntegerField(default=0, verbose_name='玩家2失败命令数')

    # 失败命令详情
    player1_failed_commands_detail = models.JSONField(default=list, verbose_name='玩家1失败命令详情')
    player2_failed_commands_detail = models.JSONField(default=list, verbose_name='玩家2失败命令详情')

    # 命令执行详情
    player1_command_execution_details = models.JSONField(default=list, verbose_name='玩家1命令执行详情')
    player2_command_execution_details = models.JSONField(default=list, verbose_name='玩家2命令执行详情')

    # 玩家script_input（仅在有错误或失败命令时保存）
    player1_battle_state = models.JSONField(default=dict, null=True, blank=True, verbose_name='玩家1战斗状态')
    player2_battle_state = models.JSONField(default=dict, null=True, blank=True, verbose_name='玩家2战斗状态')

    # 地图数据
    map_data = models.JSONField(default=dict, verbose_name='地图数据')

    # 时间信息
    timestamp = models.DateTimeField(default=timezone.now, verbose_name='回合时间戳')

    class Meta:
        verbose_name = '对战回合'
        verbose_name_plural = '对战回合'
        unique_together = ['battle', 'round_number']
        ordering = ['battle', 'round_number']
        indexes = [
            models.Index(fields=['battle', 'round_number']),
            models.Index(fields=['timestamp']),
        ]

    def __str__(self):
        return f'{self.battle} - 第{self.round_number}回合'


class BattleStatistics(models.Model):
    """对战统计数据模型"""

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='battle_stats', verbose_name='用户')

    # 基础统计
    total_battles = models.IntegerField(default=0, verbose_name='总对战数')
    wins = models.IntegerField(default=0, verbose_name='胜利数')
    losses = models.IntegerField(default=0, verbose_name='失败数')
    draws = models.IntegerField(default=0, verbose_name='平局数')

    # 高级统计
    total_score = models.IntegerField(default=0, verbose_name='总得分')
    average_score = models.FloatField(default=0.0, verbose_name='平均得分')
    best_score = models.IntegerField(default=0, verbose_name='最高得分')

    # 详细战斗统计
    total_kills = models.IntegerField(default=0, verbose_name='总击杀数')
    total_deaths = models.IntegerField(default=0, verbose_name='总死亡数')
    total_damage_dealt = models.IntegerField(default=0, verbose_name='总造成伤害')
    total_damage_received = models.IntegerField(default=0, verbose_name='总承受伤害')
    total_healing = models.IntegerField(default=0, verbose_name='总治疗量')
    total_command_fail_count = models.IntegerField(default=0, verbose_name='总命令失败数')
    total_rmb = models.IntegerField(default=0, verbose_name='总资源')
    average_base_health = models.FloatField(default=0.0, verbose_name='平均基础生命值')

    # 排名信息
    current_rank = models.IntegerField(default=0, verbose_name='当前排名')
    highest_rank = models.IntegerField(default=0, verbose_name='历史最高排名')
    rating = models.IntegerField(default=0, verbose_name='等级分')

    # 时间信息
    last_battle_at = models.DateTimeField(null=True, blank=True, verbose_name='最后对战时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '对战统计'
        verbose_name_plural = '对战统计'

    def __str__(self):
        return f'{self.user.username}的对战统计'

    def get_win_rate(self):
        """获取胜率"""
        if self.total_battles == 0:
            return 0.0
        return (self.wins / self.total_battles) * 100

    def update_detailed_stats(self, detailed_stats):
        # 更新详细统计数据
        self.total_kills += detailed_stats.get('kills', 0)
        self.total_deaths += detailed_stats.get('deaths', 0)
        self.total_damage_dealt += detailed_stats.get('totalDamageDealt', 0)
        self.total_damage_received += detailed_stats.get('totalDamageReceived', 0)
        self.total_healing += detailed_stats.get('totalHealing', 0)
        self.total_command_fail_count += detailed_stats.get('commandFailCount', 0)
        self.total_rmb += detailed_stats.get('rmb', 0)

        # 更新平均基础生命值
        base_health = detailed_stats.get('baseHealth', 0)
        if base_health > 0:
            current_total_health = self.average_base_health * (self.total_battles - 1)
            self.average_base_health = (current_total_health + base_health) / self.total_battles

        self.save()

    def get_kd_ratio(self):
        """获取KD比率"""
        if self.total_deaths == 0:
            return self.total_kills
        return self.total_kills / self.total_deaths

    def get_detailed_stats(self):
        """获取详细统计信息"""
        return {
            'total_battles': self.total_battles,
            'wins': self.wins,
            'losses': self.losses,
            'draws': self.draws,
            'win_rate': self.get_win_rate(),
            'total_score': self.total_score,
            'average_score': self.average_score,
            'best_score': self.best_score,
            'total_kills': self.total_kills,
            'total_deaths': self.total_deaths,
            'total_damage_dealt': self.total_damage_dealt,
            'total_damage_received': self.total_damage_received,
            'total_healing': self.total_healing,
            'total_command_fail_count': self.total_command_fail_count,
            'total_rmb': self.total_rmb,
            'average_base_health': self.average_base_health,
            'kd_ratio': self.get_kd_ratio(),
            'current_rank': self.current_rank,
            'highest_rank': self.highest_rank,
            'rating': self.rating,
            'last_battle_at': self.last_battle_at,
        }


class BattleExecutionLog(models.Model):
    """战斗代码执行日志模型"""

    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='execution_logs', verbose_name='用户')
    battle = models.ForeignKey(Battle, on_delete=models.CASCADE, related_name='execution_logs', verbose_name='对战记录')

    # 日志内容
    log_content = models.TextField(verbose_name='日志内容')
    log_type = models.CharField(
        max_length=20,
        choices=[('info', '信息'), ('warning', '警告'), ('error', '错误'), ('debug', '调试')],
        default='info',
        verbose_name='日志类型',
    )

    # 执行统计摘要
    total_commands = models.IntegerField(default=0, verbose_name='总命令数')
    successful_commands = models.IntegerField(default=0, verbose_name='成功命令数')
    failed_commands = models.IntegerField(default=0, verbose_name='失败命令数')

    # 时间信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        verbose_name = '战斗执行日志'
        verbose_name_plural = '战斗执行日志'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', '-created_at']),
            models.Index(fields=['battle']),
        ]

    def __str__(self):
        return f'{self.user.username} - {self.battle} - {self.log_type}'

    @classmethod
    def cleanup_old_logs(cls, user, keep_count=50):
        """清理用户的旧日志，只保留最近的指定数量"""
        logs = cls.objects.filter(user=user).order_by('-created_at')
        if logs.count() > keep_count:
            old_logs = logs[keep_count:]
            cls.objects.filter(id__in=[log.id for log in old_logs]).delete()

    def get_log_summary(self):
        """获取日志摘要"""
        return {
            'battle_id': self.battle.id,
            'total_commands': self.total_commands,
            'successful_commands': self.successful_commands,
            'failed_commands': self.failed_commands,
            'success_rate': (self.successful_commands / self.total_commands * 100) if self.total_commands > 0 else 0,
            'log_type': self.log_type,
            'created_at': self.created_at,
        }


# 匹配模式选择
MATCH_MODE_CHOICES = [
    ('realtime', '实时匹配'),
    ('random', '随机匹配'),
]

# 匹配状态选择
MATCH_STATUS_CHOICES = [
    ('waiting', '等待中'),
    ('matched', '已匹配'),
    ('cancelled', '已取消'),
    ('expired', '已过期'),
]


class MatchQueue(models.Model):
    """匹配队列模型"""

    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='match_queues', verbose_name='用户')
    code = models.ForeignKey(Code, on_delete=models.CASCADE, verbose_name='参战代码')

    # 匹配信息
    match_mode = models.CharField(max_length=20, choices=MATCH_MODE_CHOICES, verbose_name='匹配模式')
    status = models.CharField(max_length=20, choices=MATCH_STATUS_CHOICES, default='waiting', verbose_name='状态')



    # 游戏配置
    round_limit = models.IntegerField(default=100, verbose_name='最大回合数')
    time_limit = models.IntegerField(default=30, verbose_name='时间限制(秒)')
    save_round_inputs = models.BooleanField(default=False, verbose_name='保存回合输入数据')
    is_public = models.BooleanField(default=True, verbose_name='是否公开')

    # 时间信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    matched_at = models.DateTimeField(null=True, blank=True, verbose_name='匹配时间')
    expires_at = models.DateTimeField(verbose_name='过期时间')

    # 匹配结果
    matched_battle = models.ForeignKey(Battle, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='匹配的对战')

    class Meta:
        verbose_name = '匹配队列'
        verbose_name_plural = '匹配队列'
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.user.username} 的{self.get_match_mode_display()}'

    def is_expired(self):
        """检查是否已过期"""
        return timezone.now() > self.expires_at

    def cancel(self):
        """取消匹配"""
        self.status = 'cancelled'
        self.save()

    def mark_matched(self, battle):
        """标记为已匹配"""
        self.status = 'matched'
        self.matched_at = timezone.now()
        self.matched_battle = battle
        self.save()


# 世界杯比赛状态选择
WORLDCUP_STATUS_CHOICES = [
    ('preparing', '准备中'),
    ('ready', '准备就绪'),
    ('regular_season', '常规赛进行中'),
    ('regular_finished', '常规赛结束'),
    ('championship_ready', '冠军赛准备就绪'),
    ('championship', '冠军赛进行中'),
    ('finished', '已结束'),
]

# 世界杯阶段选择
WORLDCUP_STAGE_CHOICES = [
    ('regular', '常规赛'),
    ('round_16', '16强'),
    ('quarter_final', '8强'),
    ('semi_final', '4强'),
    ('final', '决赛'),
]


class WorldCup(models.Model):
    """世界杯比赛模型"""

    name = models.CharField(max_length=100, verbose_name='世界杯名称')
    description = models.TextField(blank=True, null=True, verbose_name='描述')
    status = models.CharField(max_length=20, choices=WORLDCUP_STATUS_CHOICES, default='preparing', verbose_name='状态')

    # 时间信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    regular_season_started_at = models.DateTimeField(null=True, blank=True, verbose_name='常规赛开始时间')
    regular_season_finished_at = models.DateTimeField(null=True, blank=True, verbose_name='常规赛结束时间')
    championship_started_at = models.DateTimeField(null=True, blank=True, verbose_name='冠军赛开始时间')
    finished_at = models.DateTimeField(null=True, blank=True, verbose_name='结束时间')

    # 配置信息
    round_limit = models.IntegerField(default=100, verbose_name='最大回合数')
    time_limit = models.IntegerField(default=30, verbose_name='时间限制(秒)')

    # 统计信息
    total_participants = models.IntegerField(default=0, verbose_name='总参赛人数')
    total_regular_matches = models.IntegerField(default=0, verbose_name='常规赛总场次')
    completed_regular_matches = models.IntegerField(default=0, verbose_name='已完成常规赛场次')

    # 阶段转换信息
    stage_transition_info = models.JSONField(default=dict, blank=True, verbose_name='阶段转换信息')

    class Meta:
        verbose_name = '世界杯比赛'
        verbose_name_plural = '世界杯比赛'
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.name} - {self.get_status_display()}'

    def get_top_16_participants(self):
        """获取前16名参赛者（基于常规赛成绩）"""
        return self.participants.all().order_by('-wins', '-total_score')[:16]

    def is_regular_season_complete(self):
        """检查常规赛是否完成"""
        return self.completed_regular_matches >= self.total_regular_matches

    def start_regular_season(self):
        """开始常规赛 - 创建所有参赛者之间的对战组合"""
        from itertools import combinations

        if self.status != 'ready':
            raise ValueError("只有准备就绪的世界杯才能开始常规赛")

        participants = list(self.participants.all())
        if len(participants) < 2:
            raise ValueError("参赛者数量不足，至少需要2名参赛者")

        # 创建所有可能的对战组合（每两个参赛者打一场）
        match_combinations = list(combinations(participants, 2))
        total_matches = len(match_combinations)

        # 批量创建常规赛比赛
        matches_to_create = []
        for i, (p1, p2) in enumerate(match_combinations):
            match = WorldCupMatch(
                worldcup=self,
                stage='regular',
                participant1=p1,
                participant2=p2,
                bracket_position=i + 1
            )
            matches_to_create.append(match)

        # 批量创建比赛记录
        WorldCupMatch.objects.bulk_create(matches_to_create)

        # 更新世界杯状态和统计信息
        self.status = 'regular_season'
        self.regular_season_started_at = timezone.now()
        self.total_regular_matches = total_matches
        self.completed_regular_matches = 0
        self.save()

        # 创建对应的Battle记录并加入队列
        self._create_regular_season_battles()

        return total_matches

    def _create_regular_season_battles(self):
        """为常规赛创建Battle记录并加入队列等待分批次启动"""
        from .battle_queue_manager import start_worldcup_regular_season_battles

        regular_matches = self.matches.filter(stage='regular', battle__isnull=True)

        battles_to_create = []
        for match in regular_matches:
            battle = Battle(
                player1=match.participant1.user,
                player2=match.participant2.user,
                player1_code=match.participant1.code,
                player2_code=match.participant2.code,
                battle_type='worldcup_regular',
                status='pending',
                game_config={
                    'round_limit': self.round_limit,
                    'time_limit': self.time_limit,
                    'is_practice': False
                }
            )
            battles_to_create.append(battle)

        # 批量创建Battle记录
        created_battles = Battle.objects.bulk_create(battles_to_create)

        # 关联Battle和WorldCupMatch
        for i, match in enumerate(regular_matches):
            match.battle = created_battles[i]
            match.save()

        # 使用队列管理器分批次启动战斗
        result = start_worldcup_regular_season_battles(self.id)
        if result['success']:
            import logging
            logger = logging.getLogger(__name__)
            logger.info(f"世界杯 {self.name} 常规赛战斗已加入队列: {result['message']}")
        else:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"世界杯 {self.name} 常规赛战斗队列启动失败: {result.get('error', '未知错误')}")

    def check_regular_season_progress(self):
        """检查常规赛进度并更新状态"""
        if self.status != 'regular_season':
            return

        # 统计已完成的常规赛比赛
        completed_matches = self.matches.filter(
            stage='regular',
            is_completed=True
        ).count()

        self.completed_regular_matches = completed_matches

        # 检查是否还有待处理的常规赛战斗
        pending_battles = Battle.objects.filter(
            battle_type='worldcup_regular',
            status='pending'
        ).filter(
            worldcupmatch__worldcup=self
        ).exists()

        # 只有在常规赛全部完成且没有待处理的战斗时才更新状态
        if self.is_regular_season_complete() and not pending_battles:
            self.status = 'regular_finished'
            self.regular_season_finished_at = timezone.now()
            # 自动生成冠军赛16强名单
            self._prepare_championship_bracket()

        self.save()

    def force_end_regular_season(self):
        """管理员强制结束常规赛"""
        if self.status != 'regular_season':
            raise ValueError('只能在常规赛进行中时强制结束')

        # 更新状态为常规赛结束
        self.status = 'regular_finished'
        self.regular_season_finished_at = timezone.now()

        # 准备冠军赛16强名单
        self._prepare_championship_bracket()

        self.save()

        return True

    def prepare_championship(self):
        """准备冠军赛 - 显示16强分组但不开始战斗"""
        if self.status != 'regular_finished':
            raise ValueError("只有常规赛结束后才能准备冠军赛")

        # 清除之前可能存在的16强比赛记录
        WorldCupMatch.objects.filter(worldcup=self, stage='round_16').delete()

        # 准备冠军赛16强名单
        top_participants = self._prepare_championship_bracket()

        # 创建16强对战（但不创建Battle记录）
        matches_to_create = []
        bracket_position = 1

        # 确保参赛者数量为偶数，如果是奇数则最后一个参赛者轮空
        participants_count = len(top_participants)

        if participants_count == 0:
            raise ValueError("没有参赛者可以进入16强")

        # 公平配对创建首轮比赛，确保后续8强4强匹配公平
        # 新的匹配规则
        if participants_count >= 16:
            # 标准16强匹配规则
            match_pairs = [
                (0, 15),   # R16-1: 第1名 vs 第16名
                (7, 8),    # R16-2: 第8名 vs 第9名
                (4, 11),   # R16-3: 第5名 vs 第12名
                (3, 12),   # R16-4: 第4名 vs 第13名

                (2, 13),   # R16-5: 第3名 vs 第14名
                (5, 10),   # R16-6: 第6名 vs 第11名
                (6, 9),    # R16-7: 第7名 vs 第10名
                (1, 14),   # R16-8: 第2名 vs 第15名
            ]

            for i, (idx1, idx2) in enumerate(match_pairs):
                if idx1 < participants_count and idx2 < participants_count:
                    participant1 = top_participants[idx1]
                    participant2 = top_participants[idx2]

                    match = WorldCupMatch(
                        worldcup=self,
                        stage='round_16',
                        participant1=participant1,
                        participant2=participant2,
                        bracket_position=bracket_position
                    )
                    matches_to_create.append(match)
                    bracket_position += 1
        else:
            # 参赛者不足16人时，使用原有的简单配对逻辑
            half_count = participants_count // 2
            for i in range(half_count):
                # 第i+1名 vs 第(participants_count-i)名
                participant1 = top_participants[i]  # 排名较高的
                participant2 = top_participants[participants_count - 1 - i]  # 排名较低的

                match = WorldCupMatch(
                    worldcup=self,
                    stage='round_16',
                    participant1=participant1,
                    participant2=participant2,
                    bracket_position=bracket_position
                )
                matches_to_create.append(match)
                bracket_position += 1

        # 如果参赛者数量为奇数，最后一个参赛者自动晋级到下一轮
        if len(top_participants) % 2 == 1:
            # 最后一个参赛者直接晋级，不需要创建比赛
            last_participant = top_participants[-1]
            last_participant.stage = 'quarter_final'  # 16强的下一轮是8强
            last_participant.save()

        # 批量创建16强比赛
        if matches_to_create:
            WorldCupMatch.objects.bulk_create(matches_to_create)

        # 更新世界杯状态为冠军赛准备就绪
        self.status = 'championship_ready'
        self.save()

        return top_participants

    def _prepare_championship_bracket(self):
        """准备冠军赛16强名单"""
        # 首先重置所有参赛者状态为常规赛
        all_participants = self.participants.all()
        for participant in all_participants:
            participant.stage = 'regular'
            participant.is_eliminated = False
            participant.eliminated_at_stage = None
            participant.save()

        # 获取常规赛前16名
        top_participants = self.get_top_16_participants()

        # 严格限制为16个参赛者
        if len(top_participants) > 16:
            top_16 = list(top_participants[:16])
        elif len(top_participants) < 16:
            top_16 = list(top_participants)
        else:
            top_16 = list(top_participants)

        # 更新参赛者阶段状态
        for participant in top_16:
            participant.stage = 'round_16'
            participant.save()

        # 淘汰未进入16强的参赛者
        eliminated_participants = self.participants.exclude(
            id__in=[p.id for p in top_16]
        )
        for participant in eliminated_participants:
            participant.is_eliminated = True
            participant.eliminated_at_stage = 'regular'
            participant.save()

        return top_16

    def start_championship(self):
        """开始冠军赛"""
        if self.status != 'championship_ready':
            raise ValueError("只有冠军赛准备就绪后才能开始冠军赛")

        # 获取16强参赛者
        top_16 = list(self.participants.filter(
            stage='round_16',
            is_eliminated=False
        ).order_by('-wins', '-total_score')[:16])

        if len(top_16) < 2:
            raise ValueError("进入冠军赛的参赛者不足")

        # 更新世界杯状态
        self.status = 'championship'
        self.championship_started_at = timezone.now()
        self.save()

        # 创建对应的Battle记录
        self._create_championship_battles('round_16')

    def _create_championship_battles(self, stage):
        """为冠军赛指定阶段创建Battle记录并加入队列"""
        from .battle_queue_manager import start_worldcup_championship_battles

        championship_matches = self.matches.filter(
            stage=stage,
            battle__isnull=True
        )

        battles_to_create = []
        for match in championship_matches:
            battle = Battle(
                player1=match.participant1.user,
                player2=match.participant2.user,
                player1_code=match.participant1.code,
                player2_code=match.participant2.code,
                battle_type='worldcup_championship',
                status='pending',
                game_config={
                    'round_limit': self.round_limit,
                    'time_limit': self.time_limit,
                    'is_practice': False
                }
            )
            battles_to_create.append(battle)

        # 批量创建Battle记录
        created_battles = Battle.objects.bulk_create(battles_to_create)

        # 关联Battle和WorldCupMatch
        for i, match in enumerate(championship_matches):
            match.battle = created_battles[i]
            match.save()

        # 使用队列管理器分批次启动战斗
        result = start_worldcup_championship_battles(self.id, stage)
        if result['success']:
            import logging
            logger = logging.getLogger(__name__)
            logger.info(f"世界杯 {self.name} {stage}战斗已加入队列: {result['message']}")
        else:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"世界杯 {self.name} {stage}战斗队列启动失败: {result.get('error', '未知错误')}")


class WorldCupParticipant(models.Model):
    """世界杯参赛者模型"""

    worldcup = models.ForeignKey(WorldCup, on_delete=models.CASCADE, related_name='participants', verbose_name='世界杯')
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='参赛用户')
    code = models.ForeignKey(Code, on_delete=models.CASCADE, verbose_name='参赛代码')
    stage = models.CharField(max_length=20, choices=WORLDCUP_STAGE_CHOICES, default='regular', verbose_name='当前阶段')

    # 常规赛统计
    regular_matches_played = models.IntegerField(default=0, verbose_name='常规赛已比赛场次')
    wins = models.IntegerField(default=0, verbose_name='胜场')
    losses = models.IntegerField(default=0, verbose_name='负场')
    draws = models.IntegerField(default=0, verbose_name='平局')
    total_score = models.IntegerField(default=0, verbose_name='总积分')

    # 冠军赛统计
    championship_matches_played = models.IntegerField(default=0, verbose_name='冠军赛已比赛场次')
    championship_wins = models.IntegerField(default=0, verbose_name='冠军赛胜场')
    championship_rank = models.IntegerField(null=True, blank=True, verbose_name='冠军赛排名')

    # 状态
    is_eliminated = models.BooleanField(default=False, verbose_name='是否被淘汰')
    eliminated_at_stage = models.CharField(max_length=20, choices=WORLDCUP_STAGE_CHOICES, null=True, blank=True, verbose_name='淘汰阶段')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='参赛时间')

    class Meta:
        verbose_name = '世界杯参赛者'
        verbose_name_plural = '世界杯参赛者'
        unique_together = ['worldcup', 'user']
        ordering = ['-wins', '-total_score']

    def __str__(self):
        return f'{self.worldcup.name} - {self.user.username}'

    def get_win_rate(self):
        """获取胜率"""
        total_matches = self.regular_matches_played
        if total_matches == 0:
            return 0
        return (self.wins / total_matches) * 100

    def get_regular_season_rank(self):
        """获取常规赛排名"""
        participants = self.worldcup.participants.order_by('-wins', '-total_score')
        for i, participant in enumerate(participants, 1):
            if participant.id == self.id:
                return i
        return None


class WorldCupMatch(models.Model):
    """世界杯比赛场次模型"""

    worldcup = models.ForeignKey(WorldCup, on_delete=models.CASCADE, related_name='matches', verbose_name='世界杯')
    stage = models.CharField(max_length=20, choices=WORLDCUP_STAGE_CHOICES, verbose_name='比赛阶段')

    # 对战双方
    participant1 = models.ForeignKey(WorldCupParticipant, on_delete=models.CASCADE, related_name='matches_as_p1', verbose_name='参赛者1')
    participant2 = models.ForeignKey(WorldCupParticipant, on_delete=models.CASCADE, related_name='matches_as_p2', verbose_name='参赛者2')

    # 关联的实际对战记录
    battle = models.OneToOneField(Battle, on_delete=models.CASCADE, null=True, blank=True, verbose_name='对战记录')

    # 冠军赛特有字段
    bracket_position = models.IntegerField(null=True, blank=True, verbose_name='对战图位置')
    next_match = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='下一轮比赛')

    # 状态
    is_completed = models.BooleanField(default=False, verbose_name='是否完成')
    winner = models.ForeignKey(WorldCupParticipant, on_delete=models.SET_NULL, null=True, blank=True, related_name='won_matches', verbose_name='获胜者')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    completed_at = models.DateTimeField(null=True, blank=True, verbose_name='完成时间')

    class Meta:
        verbose_name = '世界杯比赛场次'
        verbose_name_plural = '世界杯比赛场次'
        ordering = ['stage', 'bracket_position', 'created_at']
        indexes = [
            models.Index(fields=['worldcup', 'stage']),
            models.Index(fields=['is_completed']),
        ]

    def __str__(self):
        return f'{self.worldcup.name} {self.get_stage_display()} - {self.participant1.user.username} vs {self.participant2.user.username}'

    def update_from_battle_result(self):
        """根据对战结果更新比赛状态"""
        if not self.battle or self.battle.status != 'finished':
            return

        # 确定获胜者
        if self.battle.result == 'player1_win':
            self.winner = self.participant1
        elif self.battle.result == 'player2_win':
            self.winner = self.participant2

        # 更新参赛者统计
        if self.stage == 'regular':
            self._update_regular_season_stats()
            # 检查常规赛是否全部完成，如果是则自动转换状态
            self.worldcup.check_regular_season_progress()
        else:
            self._update_championship_stats()
            # 冠军赛阶段：推进获胜者到下一轮并检查是否需要创建下一阶段
            self._advance_winner_to_next_round()
            self._check_and_create_next_round()

        # 设置比赛完成状态
        self.is_completed = True
        self.completed_at = timezone.now()

        # 保存所有更改
        self.save()

    def _update_regular_season_stats(self):
        """更新常规赛统计"""
        if self.is_completed:
            return

        self.participant1.regular_matches_played += 1
        self.participant2.regular_matches_played += 1

        if self.battle.result == 'player1_win':
            self.participant1.wins += 1
            self.participant1.total_score += self.battle.player1_score
            self.participant2.losses += 1
            self.participant2.total_score += self.battle.player2_score
        elif self.battle.result == 'player2_win':
            self.participant2.wins += 1
            self.participant2.total_score += self.battle.player2_score
            self.participant1.losses += 1
            self.participant1.total_score += self.battle.player1_score
        else:  # 平局
            self.participant1.draws += 1
            self.participant1.total_score += self.battle.player1_score
            self.participant2.draws += 1
            self.participant2.total_score += self.battle.player2_score

        self.participant1.save()
        self.participant2.save()

    def _update_championship_stats(self):
        """更新冠军赛统计"""
        if self.is_completed:
            return

        self.participant1.championship_matches_played += 1
        self.participant2.championship_matches_played += 1

        if self.winner:
            self.winner.championship_wins += 1
            # 失败者被淘汰
            loser = self.participant2 if self.winner == self.participant1 else self.participant1
            loser.is_eliminated = True
            loser.eliminated_at_stage = self.stage
            loser.save()

        self.participant1.save()
        self.participant2.save()

        # 如果有下一轮比赛，将获胜者推进
        if self.winner and self.next_match:
            self._advance_winner_to_next_round()

    def _advance_winner_to_next_round(self):
        """将获胜者晋级到下一轮"""
        if not self.winner or self.stage == 'regular':
            return

        # 更新获胜者的阶段状态
        if self.stage == 'round_16':
            self.winner.stage = 'quarter_final'
        elif self.stage == 'quarter_final':
            self.winner.stage = 'semi_final'
        elif self.stage == 'semi_final':
            self.winner.stage = 'final'

        self.winner.save()

        # 淘汰失败者
        loser = self.participant2 if self.winner == self.participant1 else self.participant1
        loser.is_eliminated = True
        loser.eliminated_at_stage = self.stage
        loser.save()

        # 检查是否需要创建下一轮比赛
        self._check_and_create_next_round()

        return {
            'winner': self.winner,
            'loser': loser,
            'next_stage': self.winner.stage
        }

    def _check_and_create_next_round(self):
        """检查并创建下一轮比赛"""
        if self.stage == 'final':
            # 决赛结束，设置冠军赛排名
            self._set_championship_rankings()
            return

        # 获取当前阶段的所有比赛
        current_stage_matches = self.worldcup.matches.filter(stage=self.stage)
        completed_matches = current_stage_matches.filter(is_completed=True)

        # 如果当前阶段所有比赛都完成了，创建下一轮
        if current_stage_matches.count() == completed_matches.count():
            next_stage = self._get_next_stage()
            if next_stage:
                self._create_next_stage_matches(next_stage)

    def _get_next_stage(self):
        """获取下一个比赛阶段"""
        stage_progression = {
            'round_16': 'quarter_final',
            'quarter_final': 'semi_final',
            'semi_final': 'final'
        }
        return stage_progression.get(self.stage)

    def _create_next_stage_matches(self, next_stage):
        """创建下一阶段的比赛"""
        # 检查下一阶段的比赛是否已经存在，避免重复创建
        existing_next_stage_matches = self.worldcup.matches.filter(stage=next_stage)
        if existing_next_stage_matches.exists():
            # 下一阶段比赛已存在，无需重复创建
            return

        # 获取当前阶段的所有获胜者
        current_winners = []
        current_stage_matches = self.worldcup.matches.filter(
            stage=self.stage,
            is_completed=True
        ).order_by('bracket_position')

        for match in current_stage_matches:
            if match.winner:
                current_winners.append(match.winner)

        # 两两配对创建下一轮比赛
        matches_to_create = []
        bracket_position = 1

        for i in range(0, len(current_winners), 2):
            if i + 1 < len(current_winners):
                match = WorldCupMatch(
                    worldcup=self.worldcup,
                    stage=next_stage,
                    participant1=current_winners[i],
                    participant2=current_winners[i + 1],
                    bracket_position=bracket_position
                )
                matches_to_create.append(match)
                bracket_position += 1

        # 如果参赛者数量为奇数，最后一个参赛者自动晋级到下一轮
        if len(current_winners) % 2 == 1:
            # 最后一个参赛者直接晋级，不需要创建比赛
            last_participant = current_winners[-1]
            last_participant.stage = next_stage
            last_participant.save()

        # 批量创建冠军赛比赛
        if matches_to_create:
            WorldCupMatch.objects.bulk_create(matches_to_create)
            self.worldcup._create_championship_battles(next_stage)

    def _set_championship_rankings(self):
        """设置冠军赛最终排名"""
        # 决赛获胜者为冠军（排名1）
        if self.winner:
            self.winner.championship_rank = 1
            self.winner.save()

        # 决赛失败者为亚军（排名2）
        loser = self.participant2 if self.winner == self.participant1 else self.participant1
        loser.championship_rank = 2
        loser.save()

        # 设置 semifinal比赛失败者为第3、4名
        semi_final_matches = self.worldcup.matches.filter(
            stage='semi_final',
            is_completed=True
        )
        rank = 3
        for match in semi_final_matches:
            semi_loser = match.participant2 if match.winner == match.participant1 else match.participant1
            if not semi_loser.championship_rank:  # 避免重复设置
                semi_loser.championship_rank = rank
                semi_loser.save()
                rank += 1

        # 设置8强失败者为第5-8名
        quarter_final_matches = self.worldcup.matches.filter(
            stage='quarter_final',
            is_completed=True
        )
        rank = 5
        for match in quarter_final_matches:
            quarter_loser = match.participant2 if match.winner == match.participant1 else match.participant1
            if not quarter_loser.championship_rank:  # 避免重复设置
                quarter_loser.championship_rank = rank
                quarter_loser.save()
                rank += 1

        # 设置16强失败者为第9-16名
        round_16_matches = self.worldcup.matches.filter(
            stage='round_16',
            is_completed=True
        )
        rank = 9
        for match in round_16_matches:
            round_16_loser = match.participant2 if match.winner == match.participant1 else match.participant1
            if not round_16_loser.championship_rank:  # 避免重复设置
                round_16_loser.championship_rank = rank
                round_16_loser.save()
                rank += 1

        # 标记世界杯结束
        self.worldcup.status = 'finished'
        self.worldcup.finished_at = timezone.now()
        self.worldcup.save()
